package com.eet.juc.demo;

import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 传统的生产者消费者问题
 *
 * @author zheng.zhang
 */
public class ProductAndConsumer3 {
    private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(3, 5, 1L,
            TimeUnit.SECONDS, new LinkedBlockingDeque<>(),
            Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        Data3 data = new Data3();
        // 创建线程1
        Future<?> submit1 = EXECUTOR.submit(() -> {
            for (int i = 0; i < 10; i++) {
                data.printA();
            }
        });

        // 创建线程2
        Future<?> submit2 = EXECUTOR.submit(() -> {
            for (int i = 0; i < 10; i++) {
                data.printB();
            }
        });

        // 创建线程3
        Future<?> submit3 = EXECUTOR.submit(() -> {
            for (int i = 0; i < 10; i++) {
                data.printC();
            }
        });
    }
}

/**
 * 数字资源类
 * 等待->业务->通知
 */
class Data3 {
    private int number = 1;
    private final Lock lock = new ReentrantLock();
    private final Condition condition1 = lock.newCondition();
    private final Condition condition2 = lock.newCondition();
    private final Condition condition3 = lock.newCondition();

    /**
     * 打印A
     */
    public void printA() {
        lock.lock();
        try {
            while (number != 1) {
                // 等待
                condition1.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + " => " + number);
            // 通知其他线程, 我+1完毕了
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    /**
     * 打印B
     */
    public void printB() {
        lock.lock();
        try {
            while (number != 2) {
                // 等待
                condition2.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + " => " + number);
            // 通知其他线程, 我-1完毕了
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 打印C
     */
    public void printC() {
        lock.lock();
        try {
            while (number != 3) {
                // 等待
                condition3.await();
            }
            number = 1;
            System.out.println(Thread.currentThread().getName() + " => " + number);
            // 通知其他线程, 我-1完毕了
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}